/**
 * MinIO 文件管理服务
 * 负责与后端文件管理接口交互
 * 支持自动切换Mock数据和真实API
 */

import ApiClient from '../client.js';
import { API_CONFIG } from '../config.js';
import { createModuleAdapter } from '../adapters/api-adapter.js';

/**
 * 文件真实API服务类
 * 负责调用后端Java Spring Boot API
 */
class FileRealApiService {
  constructor() {
    this.client = new ApiClient();
    this.client.baseURL = API_CONFIG.DOCUMENTATION.BASE_URL;
  }

  /**
   * 上传文件到 MinIO
   * @param {File} file - 要上传的文件
   * @param {object} params - 额外参数（fileType, documentId, accessPolicy 等）
   * @param {Function} onProgress - 上传进度回调函数
   * @returns {Promise<object>} 文件元数据
   */
  async upload(file, params = {}, onProgress = null) {
    if (!file) {
      throw new Error('请先选择文件');
    }

    const formData = new FormData();
    formData.append('file', file);

    Object.entries(params).forEach(([key, value]) => {
      if (value !== undefined && value !== null && value !== '') {
        formData.append(key, value);
      }
    });

    // 使用 XMLHttpRequest 支持进度回调
    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();

      // 上传进度
      if (onProgress) {
        xhr.upload.addEventListener('progress', (e) => {
          if (e.lengthComputable) {
            const percent = Math.round((e.loaded * 100) / e.total);
            onProgress(percent);
          }
        });
      }

      // 请求完成
      xhr.addEventListener('load', () => {
        if (xhr.status >= 200 && xhr.status < 300) {
          try {
            const result = JSON.parse(xhr.responseText);
            // 处理后端 ApiResponse 格式：{ success: true, data: {...} }
            if (result && typeof result === 'object' && 'success' in result) {
              if (result.success === false) {
                // 如果 success 为 false，抛出错误
                const errorMessage = result.message || result.error?.message || '上传失败';
                reject(new Error(errorMessage));
                return;
              }
              // 如果 success 为 true，返回 data 字段
              resolve(result.data);
            } else {
              // 如果不是 ApiResponse 格式，直接返回
              resolve(result);
            }
          } catch {
            reject(new Error('响应解析失败'));
          }
        } else {
          // HTTP 状态码错误，尝试解析错误响应
          try {
            const errorResult = JSON.parse(xhr.responseText);
            const errorMessage = errorResult?.message || errorResult?.error?.message || xhr.responseText || `上传失败: ${xhr.status}`;
            reject(new Error(errorMessage));
          } catch {
            reject(new Error(xhr.responseText || `上传失败: ${xhr.status}`));
          }
        }
      });

      // 请求错误
      xhr.addEventListener('error', () => {
        reject(new Error('网络错误'));
      });

      // 请求中止
      xhr.addEventListener('abort', () => {
        reject(new Error('上传已取消'));
      });

      // 发送请求
      xhr.open('POST', `${this.client.baseURL}/files/upload`);

      // 添加认证头
      const token = this.getToken();
      if (token) {
        xhr.setRequestHeader('Authorization', `Bearer ${token}`);
      }

      xhr.send(formData);
    });
  }

  /**
   * 批量上传文件
   * @param {File[]} files - 要上传的文件数组
   * @param {object} params - 额外参数
   * @param {Function} onProgress - 批量上传进度回调
   * @returns {Promise<object[]>} 文件元数据数组
   */
  async batchUpload(files, params = {}, onProgress = null) {
    if (!files || files.length === 0) {
      throw new Error('请先选择文件');
    }

    const results = [];
    const total = files.length;

    for (let i = 0; i < files.length; i++) {
      const file = files[i];
      try {
        const result = await this.upload(file, params, (percent) => {
          // 计算整体进度
          if (onProgress) {
            const overallProgress = Math.round(((i * 100) + percent) / total);
            onProgress(overallProgress, i + 1, total);
          }
        });
        results.push({ success: true, data: result });
      } catch (error) {
        results.push({ success: false, error: error.message, fileName: file.name });
      }
    }

    return results;
  }

  /**
   * 上传 Markdown 文本到 MinIO
   * @param {string} markdownContent - Markdown 内容
   * @param {object} params - 额外参数（fileName, documentId 等）
   * @returns {Promise<object>} 文件元数据
   */
  async uploadMarkdown(markdownContent, params = {}) {
    // ApiClient 已自动提取 ApiResponse 的 data 字段
    return await this.client.post('/files/upload-markdown', {
      content: markdownContent,
      ...params
    });
  }

  /**
   * 获取文件列表
   * @param {object} params - 查询参数
   * @returns {Promise<object>} 分页数据
   */
  async getList(params = {}) {
    // ApiClient 已自动提取 ApiResponse 的 data 字段
    return await this.client.get('/files', {
      query: params,
    });
  }

  /**
   * 获取文件详情
   * @param {number|string} id - 文件ID
   * @returns {Promise<object>} 文件元数据
   */
  async getById(id) {
    // ApiClient 已自动提取 ApiResponse 的 data 字段
    return await this.client.get(`/files/${id}`);
  }

  /**
   * 获取文件下载链接
   * @param {number|string} id - 文件ID
   * @param {object} params - 额外参数（如有效期）
   * @returns {Promise<object>} 下载信息
   */
  async getDownloadUrl(id, params = {}) {
    // ApiClient 已自动提取 ApiResponse 的 data 字段
    return await this.client.get(`/files/${id}/download`, {
      query: params,
    });
  }

  /**
   * 获取文档关联的文件列表
   * @param {number|string} documentId - 文档ID
   * @returns {Promise<object[]>} 文件列表
   */
  async getByDocumentId(documentId) {
    // ApiClient 已自动提取 ApiResponse 的 data 字段
    return await this.client.get(`/files/document/${documentId}`);
  }

  /**
   * 删除文件
   * @param {number|string} id - 文件ID
   * @returns {Promise<object>} 删除结果
   */
  async delete(id) {
    // ApiClient 已自动提取 ApiResponse 的 data 字段
    return await this.client.delete(`/files/${id}`);
  }

  /**
   * 获取认证 Token
   * @returns {string|null}
   */
  getToken() {
    if (typeof window === 'undefined') return null;
    return localStorage.getItem('auth_token') || sessionStorage.getItem('auth_token');
  }
}

/**
 * 文件Mock数据服务类
 * 提供文件相关的Mock数据操作
 */
class FileMockService {
  /**
   * 模拟文件上传
   * @param {File} file - 文件对象
   * @param {object} params - 上传参数
   * @param {Function} onProgress - 进度回调
   * @returns {Promise<object>} 文件元数据
   */
  static async upload(file, params = {}, onProgress = null) {
    // 模拟上传进度
    if (onProgress) {
      for (let i = 0; i <= 100; i += 10) {
        await new Promise(resolve => setTimeout(resolve, 50));
        onProgress(i);
      }
    } else {
      await new Promise(resolve => setTimeout(resolve, 500));
    }

    // 生成模拟文件元数据
    const fileId = Date.now();
    const fileName = file.name;
    const fileSize = file.size;
    const fileType = params.fileType || (file.type.startsWith('image/') ? 'image' : 'document');
    const mimeType = file.type;

    return {
      id: fileId,
      fileName: fileName,
      filePath: `${fileType === 'image' ? 'doc-images' : 'doc-attachments'}/2024/11/${fileId}-${fileName}`,
      fileUrl: `http://localhost:9000/${fileType === 'image' ? 'doc-images' : 'doc-attachments'}/2024/11/${fileId}-${fileName}`,
      thumbnailUrl: fileType === 'image' ? `http://localhost:9000/thumbnails/2024/11/${fileId}_thumb-${fileName}` : null,
      fileSize: fileSize,
      mimeType: mimeType,
      fileType: fileType,
      width: fileType === 'image' ? 1920 : null,
      height: fileType === 'image' ? 1080 : null,
      bucketName: fileType === 'image' ? 'doc-images' : 'doc-attachments',
      accessPolicy: params.accessPolicy || (fileType === 'image' ? 'public' : 'private'),
      documentId: params.documentId ? Number(params.documentId) : null,
      uploadedBy: '550e8400-e29b-41d4-a716-446655440000',
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString()
    };
  }

  /**
   * 批量上传
   * @param {File[]} files - 文件数组
   * @param {object} params - 上传参数
   * @param {Function} onProgress - 进度回调
   * @returns {Promise<object[]>} 文件元数据数组
   */
  static async batchUpload(files, params = {}, onProgress = null) {
    const results = [];
    const total = files.length;

    for (let i = 0; i < files.length; i++) {
      const file = files[i];
      try {
        const result = await this.upload(file, params, (percent) => {
          if (onProgress) {
            const overallProgress = Math.round(((i * 100) + percent) / total);
            onProgress(overallProgress, i + 1, total);
          }
        });
        results.push({ success: true, data: result });
      } catch (error) {
        results.push({ success: false, error: error.message, fileName: file.name });
      }
    }

    return results;
  }

  /**
   * 上传 Markdown
   * @param {string} markdownContent - Markdown 内容
   * @param {object} params - 参数
   * @returns {Promise<object>} 文件元数据
   */
  static async uploadMarkdown(markdownContent, params = {}) {
    await new Promise(resolve => setTimeout(resolve, 300));
    const fileId = Date.now();
    return {
      id: fileId,
      fileName: params.fileName || `document-${fileId}.md`,
      filePath: `doc-contents/2024/11/${fileId}.md`,
      fileUrl: `http://localhost:9000/doc-contents/2024/11/${fileId}.md`,
      fileSize: new Blob([markdownContent]).size,
      mimeType: 'text/markdown',
      fileType: 'markdown',
      bucketName: 'doc-contents',
      accessPolicy: params.accessPolicy || 'public',
      documentId: params.documentId ? Number(params.documentId) : null,
      uploadedBy: '550e8400-e29b-41d4-a716-446655440000',
      createdAt: new Date().toISOString()
    };
  }

  /**
   * 获取文件列表
   * @param {object} params - 查询参数
   * @returns {Promise<object>} 分页数据
   */
  static getList(params = {}) {
    const { page = 1, pageSize = 10, documentId } = params;

    // 模拟文件列表数据
    const mockFiles = [];
    for (let i = 0; i < pageSize; i++) {
      const id = (page - 1) * pageSize + i + 1;
      mockFiles.push({
        id: id,
        fileName: `file-${id}.jpg`,
        filePath: `doc-images/2024/11/file-${id}.jpg`,
        fileUrl: `http://localhost:9000/doc-images/2024/11/file-${id}.jpg`,
        fileSize: 1024000,
        mimeType: 'image/jpeg',
        fileType: 'image',
        documentId: documentId ? Number(documentId) : null,
        createdAt: new Date().toISOString()
      });
    }

    return {
      data: mockFiles,
      page: Number(page),
      pageSize: Number(pageSize),
      total: 100,
      totalPages: Math.ceil(100 / pageSize)
    };
  }

  /**
   * 获取文件详情
   * @param {number|string} id - 文件ID
   * @returns {Promise<object>} 文件元数据
   */
  static getById(id) {
    return {
      id: Number(id),
      fileName: `file-${id}.jpg`,
      filePath: `doc-images/2024/11/file-${id}.jpg`,
      fileUrl: `http://localhost:9000/doc-images/2024/11/file-${id}.jpg`,
      thumbnailUrl: `http://localhost:9000/thumbnails/2024/11/file-${id}_thumb.jpg`,
      fileSize: 1024000,
      mimeType: 'image/jpeg',
      fileType: 'image',
      width: 1920,
      height: 1080,
      bucketName: 'doc-images',
      accessPolicy: 'public',
      documentId: null,
      uploadedBy: '550e8400-e29b-41d4-a716-446655440000',
      createdAt: new Date().toISOString()
    };
  }

  /**
   * 获取下载链接
   * @param {number|string} id - 文件ID
   * @param {object} params - 参数
   * @returns {Promise<object>} 下载信息
   */
  static getDownloadUrl(id) {
    return {
      downloadUrl: `http://localhost:9000/doc-images/2024/11/file-${id}.jpg?X-Amz-Algorithm=...`,
      expiresIn: 3600
    };
  }

  /**
   * 获取文档关联的文件
   * @param {number|string} documentId - 文档ID
   * @returns {Promise<object[]>} 文件列表
   */
  static getByDocumentId() {
    return [
      {
        id: 1,
        fileName: 'image1.jpg',
        fileUrl: 'http://localhost:9000/doc-images/2024/11/image1.jpg',
        fileType: 'image',
        fileSize: 1024000
      },
      {
        id: 2,
        fileName: 'document.pdf',
        fileUrl: 'http://localhost:9000/doc-attachments/2024/11/document.pdf',
        fileType: 'document',
        fileSize: 2048000
      }
    ];
  }

  /**
   * 删除文件
   * @param {number|string} id - 文件ID
   * @returns {Promise<object>} 删除结果
   */
  static delete() {
    return { success: true, message: '文件删除成功' };
  }
}

// 创建适配器实例
const fileAdapter = createModuleAdapter('DOCUMENTATION', FileMockService, new FileRealApiService());

/**
 * 文件服务导出
 * 自动根据配置切换Mock和真实API
 */
export const fileService = {
  /**
   * 上传文件
   * @param {File} file - 文件对象
   * @param {object} params - 上传参数
   * @param {Function} onProgress - 进度回调
   * @returns {Promise<object>} 文件元数据
   */
  async upload(file, params = {}, onProgress = null) {
    return fileAdapter.execute('upload', file, params, onProgress);
  },

  /**
   * 批量上传文件
   * @param {File[]} files - 文件数组
   * @param {object} params - 上传参数
   * @param {Function} onProgress - 进度回调
   * @returns {Promise<object[]>} 文件元数据数组
   */
  async batchUpload(files, params = {}, onProgress = null) {
    return fileAdapter.execute('batchUpload', files, params, onProgress);
  },

  /**
   * 上传 Markdown 文本
   * @param {string} markdownContent - Markdown 内容
   * @param {object} params - 参数
   * @returns {Promise<object>} 文件元数据
   */
  async uploadMarkdown(markdownContent, params = {}) {
    return fileAdapter.execute('uploadMarkdown', markdownContent, params);
  },

  /**
   * 获取文件列表
   * @param {object} params - 查询参数
   * @returns {Promise<object>} 分页数据
   */
  async getList(params = {}) {
    return fileAdapter.execute('getList', params);
  },

  /**
   * 获取文件详情
   * @param {number|string} id - 文件ID
   * @returns {Promise<object>} 文件元数据
   */
  async getById(id) {
    return fileAdapter.execute('getById', id);
  },

  /**
   * 获取文件下载链接
   * @param {number|string} id - 文件ID
   * @param {object} params - 参数
   * @returns {Promise<object>} 下载信息
   */
  async getDownloadUrl(id, params = {}) {
    return fileAdapter.execute('getDownloadUrl', id, params);
  },

  /**
   * 获取文档关联的文件列表
   * @param {number|string} documentId - 文档ID
   * @returns {Promise<object[]>} 文件列表
   */
  async getByDocumentId(documentId) {
    return fileAdapter.execute('getByDocumentId', documentId);
  },

  /**
   * 删除文件
   * @param {number|string} id - 文件ID
   * @returns {Promise<object>} 删除结果
   */
  async delete(id) {
    return fileAdapter.execute('delete', id);
  }
};
